1 //------------------------------------------------------------------------------
2 // <copyright file="asm.cs" company="Microsoft">
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
14 //------------------------------------------------------------------------------
26 public Asm(Io ihandle
)
32 * determine the IL static type
34 private String
ilSType(int type
)
38 case Tok
.T_CHAR
: return "char";
39 case Tok
.T_SHORT
: return "int16";
42 case Tok
.T_LONG
: return "int32";
43 case Tok
.T_FLOAT
: return "float";
44 case Tok
.T_DOUBLE
: return "double float";
45 case Tok
.T_VOID
: return "void";
47 Console
.WriteLine("?Unhandled type " + type
);
55 * common routine to construct a signature string for a given varlist item
56 * requires a destination ptr, will return the updated dest ptr
58 private String
genDataTypeSig(Var e
)
63 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
65 if (e
.getSign() == Tok
.T_UNSIGNED
) /* if var is unsigned, put it in sig */
66 sb
.Append("unsigned ");
68 sb
.Append(ilSType(e
.getTypeId())); /* get the datatype */
69 return (sb
.ToString());
72 private String
genFieldRef(Var e
)
77 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
79 if (e
.getSign() == Tok
.T_UNSIGNED
) /* if var is unsigned, put it in sig */
80 sb
.Append("unsigned ");
82 sb
.Append(ilSType(e
.getTypeId())); /* get the datatype */
84 sb
.Append(Io
.GetClassname()); /* get the current classname */
86 sb
.Append(e
.getName()); /* copy the variable name */
87 return (sb
.ToString());
90 public void Load(IAsm a
)
92 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
96 Console
.WriteLine("?Load instruction with no variable ptr");
99 switch (e
.getClassId())
103 sb
.Append("\tldsfld ");
104 sb
.Append(genFieldRef(e
));
106 sb
.Append(a
.getICount());
108 sb
.Append(e
.getName());
114 sb
.Append("\tldloc ");
115 sb
.Append(e
.getIndex());
117 sb
.Append(a
.getICount());
119 sb
.Append(e
.getName());
123 sb
.Append("\tldarg ");
124 sb
.Append(e
.getIndex());
126 sb
.Append(a
.getICount());
128 sb
.Append(e
.getName());
132 Console
.Write("?Instruction load of unknown class (");
133 Console
.Write(e
.getClassId());
134 Console
.WriteLine(")");
138 io
.Out(sb
.ToString());
141 public void Store(IAsm a
)
143 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
147 Console
.WriteLine("?Store instruction with no variable ptr");
150 switch (e
.getClassId())
153 sb
.Append("\tstsfld ");
154 sb
.Append(genFieldRef(e
));
156 sb
.Append(a
.getICount());
158 sb
.Append(e
.getName());
163 sb
.Append("\tstloc ");
164 sb
.Append(e
.getIndex());
166 sb
.Append(a
.getICount());
168 sb
.Append(e
.getName());
172 sb
.Append("\tstarg ");
173 sb
.Append(e
.getIndex());
175 sb
.Append(a
.getICount());
177 sb
.Append(e
.getName());
181 Console
.Write("?Instruction load of unknown class (");
182 Console
.Write(e
.getClassId());
183 Console
.WriteLine(")");
187 io
.Out(sb
.ToString());
190 public void FuncBegin(IAsm a
)
192 Var func
= a
.getVar();
193 String funcsig
= genDataTypeSig(a
.getVar()); /* gen type info */
195 VarList x
= func
.getParams(); /* get any params */
196 String paramsig
= "";
199 int max
= x
.Length();
200 StringBuilder t
= new StringBuilder(MyC
.MAXSTR
);
201 for (int i
= 0; i
< max
; i
++)
203 Var e
= x
.FindByIndex(i
);
204 t
.Append(genDataTypeSig(e
));
208 paramsig
= t
.ToString();
210 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
211 sb
.Append("\t.method ");
214 sb
.Append(func
.getName());
218 io
.Out(sb
.ToString());
220 if (func
.getName().Equals("main")) /* special entry point for main */
221 io
.Out("\t.entrypoint\r\n");
224 public void Call(IAsm a
)
226 Var func
= a
.getVar();
227 String funcsig
= genDataTypeSig(a
.getVar()); /* gen type info */
229 VarList x
= func
.getParams(); /* get any params */
230 String paramsig
= "";
233 int max
= x
.Length();
234 StringBuilder t
= new StringBuilder(MyC
.MAXSTR
);
235 for (int i
= 0; i
< max
; i
++)
237 Var e
= x
.FindByIndex(i
);
238 t
.Append(genDataTypeSig(e
));
242 paramsig
= t
.ToString();
245 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
246 sb
.Append("\tcall ");
251 sb
.Append(a
.getICount());
253 io
.Out(sb
.ToString());
256 public void Comment(IAsm a
)
258 String sp
= a
.getComment(); /* source ptr */
260 return; // empty comment
261 sp
.Trim(); // remove extra whitespace
262 if (sp
== null || sp
.Length
== 0) /* sanity check, is there a comment? */
263 return; /* no, then nothing to do */
266 Console
.Write("Comment SP=");
267 for (int _debug_i
=0; _debug_i
<sp
.Length
;_debug_i
++)
269 int _debug_d
= sp
[_debug_i
];
270 char _debug_c
= (char) (_debug_d
+ 96);
272 Console
.Write("^"+Char
.ToString(_debug_c
));
274 Console
.Write(sp
[_debug_i
]);
276 Console
.Write(_debug_d
);
279 Console
.WriteLine(";");
281 StringBuilder buf
= new StringBuilder(MyC
.MAXSTR
); /* a buffer to work with */
283 buf
.Append(a
.getCommentLine());
287 while ((i
= sp
.IndexOf('\n', i
)) >= 0)
289 i
++; // move past the newline
290 string ts
= sp
.Substring(p
, i
-p
);
291 String s
= ts
.Trim();
293 buf
.Append(s
); // copy the substr
294 buf
.Append("\r\n"); // add the line seperator
296 buf
.Append("//"); // insert the comment block
300 buf
.Append(sp
.Substring(p
)); // append the remaining chars
303 io
.Out(buf
.ToString()); /* output the comment */
306 public void Insn(IAsm a
)
308 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
310 sb
.Append(a
.getInsn());
312 sb
.Append(a
.getICount());
314 io
.Out(sb
.ToString());
317 public void Label(IAsm a
)
319 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
320 sb
.Append(a
.getLabel());
322 io
.Out(sb
.ToString());
325 public void Branch(IAsm a
)
327 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
329 sb
.Append(a
.getInsn());
331 sb
.Append(a
.getLabel());
333 sb
.Append(a
.getICount());
335 io
.Out(sb
.ToString());
338 public void Ret(IAsm a
)
340 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
341 sb
.Append("\tret\t\t//");
342 sb
.Append(a
.getICount());
344 io
.Out(sb
.ToString());
347 public void FuncEnd()
352 public void LocalVars(VarList v
)
354 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
355 sb
.Append("\t.locals (");
356 int max
= v
.Length();
358 for (int i
= 0; i
< max
; i
++) // loop thru the local params
360 Var e
= v
.FindByIndex(i
); // indexed by number
362 switch (e
.getTypeId())
364 case Tok
.T_CHAR
: stype
= "char"; break;
365 case Tok
.T_SHORT
: stype
= "int16"; break;
367 case Tok
.T_LONG
: stype
= "int32"; break;
368 case Tok
.T_FLOAT
: stype
= "float"; break;
369 case Tok
.T_DOUBLE
: stype
= "double float"; break;
371 Console
.WriteLine("?Could not find type for local\n");
375 sb
.Append(stype
); // append it now
377 sb
.Append(","); // if not last, seperate with comma
381 io
.Out(sb
.ToString());
384 public void FieldDef(IAsm a
)
386 Var e
= a
.getVar(); /* get the field var ptr */
388 switch (e
.getClassId())
391 prefix
= "\t.field ";
395 prefix
= "\t.field ";
398 Console
.WriteLine("?Unhandled field def type\n");
403 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
404 sb
.Append(prefix
); /* copy the prefix */
405 sb
.Append(genDataTypeSig(e
)); /* gen type info, rets updated dp */
407 sb
.Append(e
.getName()); /* copy the variable name */
409 io
.Out(sb
.ToString());
412 public void LoadConst(IAsm a
)
414 StringBuilder sb
= new StringBuilder(MyC
.MAXSTR
);
415 int value = Convert
.ToInt32(a
.getInsn());
417 sb
.Append("\tldc.i4");
418 if (value > 127 || value < -128) /* if must use long form */
422 else if (value > 8 || value < -1) /* if must use medium form */
426 else /* else use short form */
430 sb
.Append(a
.getInsn());
432 sb
.Append(a
.getICount());
435 io
.Out(sb
.ToString());